#pragma once
#ifndef REDIS_H
#define REDIS_H

#include <hiredis/hiredis.h>
#include <thread>
#include <functional>
#include <string>

using std::string;

/**
 * Redis类，用redis作为集群聊天服务器的中间件——消息队列
 * 该消息队列可以使得集群的聊天服务器之间能够跨服务器通信
 * 包含：消息队列服务器之间连接、创建或删除通道、发布消息及通知订阅者等功能
 * 
 * redis作为集群服务器通信的基于发布-订阅消息队列时，会遇到两个难搞的bug问题，参考下面博客详细描述：
 * https://blog.csdn.net/QIANGWEIYUAN/article/details/97895611
 */
class Redis{
public:
    Redis();
    ~Redis();

    //连接redis服务器
    bool connect();

    //向redis指定通道channel发布消息
    bool publish(int channel,string message);

    //向redis指定的通道订阅消息
    bool subscribe(int channel);

    //向redis指定的通道取消订阅消息
    bool unsubscribe(int channel);

    //在独立的线程中接收订阅的消息
    void observer_channel_message();

    //初始化向业务层上报通道消息回调函数，设置回调函数
    void init_notify_handler(std::function<void(int,string)> fn);

private:
    //hiredis同步上下文对象（相当于打开一个redis客户端），负责publish发布消息
    redisContext* _publish_context;

    //hiredis同步上下文对象（相当于打开了另一个redis客户端），负责subcribe订阅消息
    redisContext* _subscribe_context;

    //回调操作，收到订阅消息，给service层上报
    std::function<void(int,string)> _notify_message_handler;
};

#endif

